package wsz.autodeliver.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import wsz.autodeliver.client.ResumeFeignClient;

/**
 * @author wsz
 * @date 2021/12/24 15:07
 **/
@RestController
@RequestMapping("autoDeliver")
public class AutoDeliverController {

    private final String serviceName = "service-resume";

    @Autowired
    private RestTemplate restTemplate;

    /**
     * Ribbon模拟：手动拼接url
     * @return
     */
    @GetMapping(value = "getResumePort")
    public Integer getResumePort() {
        // 使用ribbon不需要我们自己获取服务实例然后选择一个那么去访问了（自己的负载均衡）
        String url = "http://" + serviceName + "/resume/getPort";  // 指定服务名
        Integer forObject = restTemplate.getForObject(url, Integer.class);
        return forObject;
    }

    /**
     * Hystrix模拟,通过延时模拟熔断效果
     * @return
     */
    @HystrixCommand(
            // 线程池标识，保持唯一，否则就共用默认的线程池（默认10个）
            threadPoolKey = "getResumePortTimeOut",
            threadPoolProperties = {
                    // 线程池配置
                    @HystrixProperty(name = "coreSize", value = "1"),
                    @HystrixProperty(name = "maxQueueSize", value = "20")
            },
            commandProperties = {
                    // 熔断超时限制2s
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
            }
    )
    @GetMapping(value = "getResumePortTimeOut")
    public Integer getResumePortTimeOut() {
        // 使用ribbon不需要我们自己获取服务实例然后选择一个那么去访问了（自己的负载均衡）
        String url = "http://" + serviceName + "/resume/getPortTimeout";  // 指定服务名
        Integer forObject = restTemplate.getForObject(url, Integer.class);
        return forObject;
    }

    /**
     * Hystrix+fallBack
     * @return
     */
    @HystrixCommand(
            // 线程池标识，保持唯一，否则就共用默认的线程池（默认10个）
            threadPoolKey = "getResumePortTimeOut",
            threadPoolProperties = {
                    // 线程池配置
                    @HystrixProperty(name = "coreSize", value = "1"),
                    @HystrixProperty(name = "maxQueueSize", value = "20")
            },
            commandProperties = {
                    // 超时时间
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000"),
                    // 统计时间窗口
                    @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "8000"),
                    // 统计时间窗口内的最小请求数
                    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "2"),
                    // 统计时间窗口内的错误数量百分比阈值
                    @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
                    // 自我修复的活动窗口长度
                    @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "3000")
            },
            fallbackMethod = "errorFallBack"
    )
    @GetMapping(value = "getResumePortTimeOutFallBack")
    public Integer getResumePortTimeOutFallBack() {
        // 使用ribbon不需要我们自己获取服务实例然后选择一个那么去访问了（自己的负载均衡）
        String url = "http://" + serviceName + "/resume/getPortTimeout";  // 指定服务名
        Integer forObject = restTemplate.getForObject(url, Integer.class);
        return forObject;
    }

    /**
     * 参数与返回保持一致
     * @return
     */
    public Integer errorFallBack() {
        return -1;
    }

    @Autowired
    private ResumeFeignClient resumeFeignClient;

    @GetMapping(value = "findDefaultResumeState/{userId}")
    public Integer findDefaultResumeState(@PathVariable(value = "userId") Long userId) {
        return resumeFeignClient.findDefaultResumeState(userId);
    }
}
